package com.audaque.springboot.foshanupload.shiro.model; /**
 * @author zgb
 * @desc ...
 * @date 2022-08-05 16:56:52
 */

import com.audaque.springboot.foshanupload.authcore.model.currentUser.TransmittableThreadLocalCurrentUser;
import com.audaque.springboot.foshanupload.authcore.service.inface.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 负责认证用户身份和对用户进行授权
 * Realm是开发者经常需要重写的，也是Shiro的扩展点，我们可以根据需要配置多个Realm，这样可以实现多因子认证，比如用户名、邮箱、指纹等。
 * 一般可以通过继承AuthenticatingRealm重写抽象方法实现。
 */
public class ShiroRealm extends AuthorizingRealm {


    @Autowired
    private UserService userService;

    // 用户授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取当前用户
        TransmittableThreadLocalCurrentUser transmittableThreadLocalCurrentUser = (TransmittableThreadLocalCurrentUser) principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //用户的角色集合
        Set<String> roleSet = new HashSet<>();
        //用户的角色id集合
        List<Integer> roleIds = new ArrayList<>();

        // 放入角色信息
        authorizationInfo.setRoles(roleSet);
        // 放入权限信息 :根据用户的角色id集合查权限表达式集合
        List<String> permissionList = new ArrayList<>();
        authorizationInfo.setStringPermissions(new HashSet<>(permissionList));

        return authorizationInfo;
    }

    // 用户认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authToken) throws AuthenticationException {
        //获取表单认证参数
        UsernamePasswordToken token = (UsernamePasswordToken) authToken;
        String username = token.getUsername();

        TransmittableThreadLocalCurrentUser transmittableThreadLocalCurrentUser = userService.getUserByUsername(username);
        //根据username查user是否存在
        if (transmittableThreadLocalCurrentUser == null) {
            return null;
        }
        //验证账号密码
        return new SimpleAuthenticationInfo(transmittableThreadLocalCurrentUser, transmittableThreadLocalCurrentUser.getPassword(), getName());
    }
}
